home *** CD-ROM | disk | FTP | other *** search
- Date: Thu, 3 Mar 94 04:55:47 PST
- From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
- Message-Id: <9403031255.AA20565@hanauma.jpl.nasa.gov>
- To: mint@atari.archive.umich.edu
- Subject: select() for BIOS serial ports
-
- Before you get too excited, I have to warn you that this code crashes almost
- immediately when running MultiTOS. I've spent about 8 hours tracking it down
- and have gotten too frustrated, so I'm sending it out in the hopes that someone
- else will point out the obvious flaw....
-
- When run without MultiTOS, it works just fine. Gory crash details to follow.
- First, the concept - simply build a table of pointers to the Iorec's for each
- serial port. At regular intervals (I originally thought of sticking this in
- the VBL code in intr.spp) check each head & tail pointer in each iorec, and
- if they're different, wake up any waiting processes. Simplicity itself. The
- actual check here occurs in the sleep routine, just like the checkkeys stuff
- works. I create a table of up to 4 entries (bios devices 6 to 9) to record
- the relevant pointers. (Anyone writing new device drivers for the Atari ought
- to do a full-blown job, like Thierry's modm0dev, so I'm not worried about
- supporting new bconmap'd devices...) The table contains a pointer to the input
- and output records of the port, and a pointer to the rsel and wsel entries in
- the corresponding tty struct. (There's actually space to keep all this in the
- tty structs themselves, if we take over some of the reserved fields, but I
- decided to keep things separate for now since I only want to deal with existing
- BIOS ttys, and not clutter up the tty struct with stuf that's not universally
- applicable...)
-
- Here's the code:
- --- 1.2 1994/03/02 08:06:50
- +++ bios.c 1994/03/03 01:50:54
- @@ -23,4 +23,5 @@
- #define AUXDEV 1
- #define PRNDEV 0
- +#define SERDEV 6 /* First serial port */
-
- /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
- @@ -33,4 +34,6 @@
- /* tty structures for the BIOS devices -- see biosfs.c */
- extern struct tty con_tty, aux_tty, midi_tty;
- +extern struct bios_tty bttys[];
- +extern short btty_max;
-
- extern int tosvers; /* from main.c */
- @@ -96,4 +99,27 @@
- }
-
- +void
- +checkbttys(void)
- +{
- + struct bios_tty *b;
- + long *l;
- +
- + for (b=bttys;b->irec;b++) {
- + if (b->irec->head != b->irec->tail) {
- + wake(IO_Q, (long)b);
- + l = b->rsel;
- + if (*l)
- + wakeselect(*l);
- + }
- + l = b->wsel;
- + if (*l) {
- + short i = b->orec->tail - b->orec->head;
- + if (i < 0)
- + i += b->orec->buflen;
- + if (i < b->orec->hi_water)
- + wakeselect(*l);
- + }
- + }
- +}
-
- /*
- @@ -181,8 +207,17 @@
- }
- else {
- - if (dev == AUXDEV && has_bconmap)
- - dev = curproc->bconmap;
- -
- - if (dev > 0) {
- + if (dev == AUXDEV) {
- + if (has_bconmap) {
- + dev = curproc->bconmap;
- + h = dev-SERDEV;
- + } else
- + h = 0;
- + } else
- + h = dev-SERDEV;
- +
- + if (h >= 0 && h < btty_max) {
- + if (!BCONSTAT(dev))
- + sleep(IO_Q, (long)&bttys[h]);
- + } else if (dev > 0) {
- unsigned long tick;
-
- --- 1.4 1994/03/02 08:20:52
- +++ biosfs.c 1994/03/03 01:11:24
- @@ -147,4 +147,9 @@
- };
-
- +#define MAX_BTTY 4 /* 4 bios_tty structs */
- +
- +struct bios_tty bttys[MAX_BTTY];
- +short btty_max;
- +
- /* Does the fcookie fc refer to the \dev\fd directory? */
- #define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
- @@ -205,12 +210,17 @@
- biosfs_init()
- {
- - struct bios_file *b;
- + struct bios_file *b, *c;
- int majdev, mindev;
- + int i;
-
- broot = BDEV;
-
- + c = 0L;
- for (b = broot; b->name[0]; b++) {
- b->next = b+1;
-
- + /* Save a pointer to the first serial port */
- + if (b->private == 6)
- + c = b;
- /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
- * device 1
- @@ -234,4 +244,15 @@
- b->next = 0;
- }
- + /* Initialize bios_tty structures */
- + for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
- + if (has_bconmap)
- + Bconmap(c->private);
- + bttys[i].irec = Iorec(0);
- + bttys[i].orec = bttys[i].irec+1;
- + bttys[i].rsel = &(c->tty->rsel);
- + bttys[i].wsel = &(c->tty->wsel);
- + }
- + btty_max = i;
- +
- defaultaux = new_fileptr();
- defaultaux->links = 1; /* so it never gets freed */
- --- 1.3 1994/03/02 08:13:00
- +++ proto.h 1994/03/03 00:13:14
- @@ -1,4 +1,5 @@
- /* bios.c */
- long ARGS_ON_STACK getmpb P_((void *ptr));
- +void checkbttys P_((void));
- long bconstat P_((int dev));
- long bconin P_((int dev));
- --- 1.3 1994/03/02 08:21:12
- +++ file.h 1994/03/02 23:51:16
- @@ -502,4 +502,11 @@
- };
-
- +struct bios_tty {
- + IOREC_T *irec; /* From XBIOS ... */
- + long *rsel; /* pointer to field in tty struct */
- + IOREC_T *orec; /* Same, for output... */
- + long *wsel;
- +};
- +
- /* Dcntl constants and types */
- #define DEV_NEWTTY 0xde00
-
- Here's the crash...
- pid 0 (MiNT): Pexec(7,27,,118A000)
- ... checking for memory, creating basepage, etc.
- leaving Pexec with basepage address 1194000
- Pexec(106,GEM,BP:1194000,0)
- Checking for memory for new PROC structure
- creating environment
- creating base page
- exec_region
- MEMORY VIOLATION: type=hardware AA=58425249 PC=112CB54 BP=112C9CA
- Operating system killed
-
- This is a little different from my original crash; I changed a couple lines
- of code. The old one had AA= (um, whatever "MiNT" is in hex.). This one is
- "XBRI", dunno where the 'I' came from. Basically, the crash is in the
- checkbttys routine; the memory that btty->irec points to is no longer an
- Iorec. I hadn't figured on the Iorec's themselves moving around in memory
- after the system started, I just figured you could change the buffer pointer
- inside the record. Although I guess, since loading GEM.SYS means you're
- pretty much getting a new operating system, it can put things wherever it
- wants to...
-
- The only fix I can think of right now is to compare the current contents of
- the Iorec pointer to the contents on the last check, and if they differ, call
- Bconmap and Iorec again to get the new value.
-
- [Bottom level details - the above crash is at the 6th instruction of
- checkbttys:
- movel a2,sp@-
- lea _bttys,a2
- tstl a2@
- jeq Nextloop
-
- movel a2@,a0
- movew a0@(8),d1 <--- boom.
- cmpw a0@(6),d1
- ...
- So, it looks at a btty struct, sees that it has a non-null irec pointer,
- and tries to get the head index out of the Iorec struct that irec points to.
- But, instead of there being an Iorec there, someone has installed something
- else in its place... sigh.]
-